package 磁盘空间的分配与回收;
/**
 * ************************************************************************
 * 项目名称: 操作系统 <br/>
 * 文件名称:  <br/>
 * 文件描述: 这里添加您的类文件描述，说明当前文件要包含的功能。 <br/>
 * 文件创建：10270 <br/>
 * 创建时间: 2021/5/20 <br/>
 *
 * @version v1.0 <br/>
 * ************************************************************************
 */

/**
 * @ProjectName: 操作系统
 * @ClassName: bitmap
 * @Description: 请描述该类的功能
 * @Author: 10270
 * @Date: 2021/5/20 8:37
 * @version v1.0
 */
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class d extends JFrame implements ActionListener {
    JTable table;
    JScrollPane sp1, sp2;
    JTextArea ta;
    JLabel l1, l2, l3, l4, l5;
    JTextField tf1, tf2, tf3;
    JButton b1, b2, b3, b4;
    JPanel p1, p2, p3, p4, p5, p6, p7;
    String data[][];
    String colum[];
    int sp[];//存放相对可用块
    int used[];//存放相对已用块
    int A, H;//A为可用快，H为已用块

    public static void main(String[] args) {
        new 磁盘空间的分配与回收.d();
    }

    public void init() { //功能：初始化
        int k;
        for (int i = 0; i < 30; i++) {
            for (int j = 0; j < 16; j++) {
                k = (int) (Math.random() * 2);
                //0与1两数字中进行随机
                data[i][j] = "" + k;
                table.setValueAt("" + k, i, j);
            }
        }
    }

    public d() {
        // TODO Auto-generated constructor stub
        super("位示图管理磁盘空间的分配与回收算法模拟实现");
        data = new String[30][16];
        colum = new String[16];
        sp = new int[480];
        used = new int[480];
        A = 0;
        H = 0;
        for (int i = 0; i < 16; i++) {
            colum[i] = "" + i;

        }
        table = new JTable(data, colum);
        sp1 = new JScrollPane(table);
        tf1 = new JTextField(6);
        tf2 = new JTextField(6);
        tf3 = new JTextField(8);
        ta = new JTextArea(10, 20);
        sp2 = new JScrollPane(ta);
        p1 = new JPanel(new BorderLayout());
        p2 = new JPanel(new FlowLayout());
        p3 = new JPanel(new BorderLayout());
        p4 = new JPanel(new FlowLayout());
        p5 = new JPanel(new FlowLayout());
        p6 = new JPanel(new BorderLayout());
        p7 = new JPanel(new FlowLayout());

        l1 = new JLabel("位示图");
        b1 = new JButton("位示图初始化");
        b1.addActionListener(this);
        b2 = new JButton("回收全部磁盘块");
        b2.addActionListener(this);
        p2.add(b1);
        p2.add(b2);
        p1.add(l1, "North");
        p1.add(sp1, "Center");
        p1.add(p2, "South");

        l2 = new JLabel("运行状况: ");
        l5 = new JLabel("空闲块数量: ");
        p7.add(l5);
        p7.add(tf3);
        p3.add(l2, "North");
        p3.add(p7, "South");
        p3.add(sp2, "Center");
        l3 = new JLabel("请输入需要分配的块数: ");
        l4 = new JLabel("请输入要回收的盘块号: ");
        b3 = new JButton("确认分配");
        b3.addActionListener(this);


        b4 = new JButton("确认回收");
        b4.addActionListener(this);
        p4.add(l3);
        p4.add(tf1);
        p4.add(b3);
        p5.add(l4);
        p5.add(tf2);
        p5.add(b4);
        p6.add(p4, "North");
        p6.add(p5, "Center");

        this.setLayout(new BorderLayout());
        this.add(p1, "West");
        this.add(p3, "Center");
        this.add(p6, "South");
        this.pack();
        this.setVisible(true);
    }


    public void getavail() //功能：得出可用块号与不可用块号的集合
    {
        int a;
        int b = 0, c = 0;
        A = 0;
        H = 0;
        for (int i = 0; i < 30; i++) {
            for (int j = 0; j < 16; j++) {
                if (data[i][j].equals("0")) {
                    a = i * 16 + j;//得到相对块号
                    sp[b] = a;//写入可用块集合
                    A++;
                    b++;

                } else {
                    a = i * 16 + j;//得到相对块号
                    used[c] = a;
                    H++;
                    c++;//写入不可用块号 集合
                }
            }
        }

    }


    public void allrec() {//全部收回
        ta.setText("");
        String str = "收回结果：\n";
        for (int i = 0; i < H; i++) {
            int a = used[i] / 16;
            int b = used[i] % 16 / 4;
            int c = used[i] % 16 % 4;
            data[a][4 * b + c] = "0";
            table.setValueAt("0", a, 4 * b + c);//位示图相应位置零
            str += "柱面" + a + "--磁道" + b + "--扇区" + c + "--盘块号" + used[i] + "\n";
            used[i] = 0;//位示图相应位置置零
        }
        for(int i = 0; i < 30; i++) {
            for (int j = 0; j < 16; j++) {
                table.setValueAt("0", i, j);
            }
        }
        H = 0;
        getavail();
        ta.append(str);
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        if (e.getSource() == b1) {
            init();
            getavail();
            String str6 = "" + A;
            ta.append("初始化完成\n");
            tf3.setText(str6);
        } else if (e.getSource() == b2) {
            if (A == 480) {
                ta.setText("");
                String str7 = "没有资源可回收";
                ta.append(str7);
            } else {
                allrec();
            }
            String str8 = "" + A;
            tf3.setText(str8);
        } else if (e.getSource() == b3) {
            int n;
            System.out.println(tf1.getText());
            n = Integer.parseInt(tf1.getText());
            tf1.setText("");
            if (A < n) {
                ta.setText("");
                String str1 = "空闲块不足";
                ta.append(str1);
                JOptionPane.showMessageDialog(null, "空闲块不足", "提示", JOptionPane.PLAIN_MESSAGE);
                return;
            } else {
                int j, k;
                ta.setText("");
                String str = "分配结果\n";
                int x = H;
                for (int i = 0; i < n; i++) {
                    j = sp[1] / 16;
                    k = sp[1] - j * 16;
                    used[x + 1] = sp[1];//可用块相对地址转为已用块相对地址
                    data[j][k] = "1";
                    table.setValueAt("1", j, k);//将位示图对应位置写1
                    str += "桂面" + sp[i] / 16 + "--磁道" + (sp[i] % 16) / 4 + "-- 扇区" + (sp[i] % 16) % 4 + "--盘块号: " + sp[i] + " \n";
                    A--;
                    H++;
                }
                for (int t = 0; t < A; t++) {
                    sp[t] = sp[t + n];//删除可用块中的已用块
                }
                ta.append(str);

            }
            String str2 = "" + A;
            tf3.setText(str2);
            tf1.setText("");
        } else if (e.getSource() == b4) {
            int num;
            num = Integer.parseInt(tf2.getText());
            ta.setText("");
            String str = "";
            int j, k = 0;
            int a = num / 16;//柱面
            int b = num % 16 / 4;//磁道
            int c = num % 16 % 4;//扇区
            if (data[a][4 * b + c].equals("0")) {
                JOptionPane.showInternalMessageDialog(null, "不可回收空闲块", "提示", JOptionPane.PLAIN_MESSAGE);
                //tf2.setText(" ");
                System.out.println("不可回收");
                return;

            } else {
                data[a][4 * b + c] = "0";
                table.setValueAt("0", a, 4 * b + c);
                str += "柱面" + a + "磁道" + b + "扇区" + c + "盘快号" + num + "\n";
                A++;
                H--;
                for (int i = 0; i < H; i++) {
                    if (used[i] == num) {
                        k = i;
                        break;
                    }
                }
                for (j = k; j < H; j++) {
                    used[j] = used[j + 1];//将回收的块号从以用中删除
                    ta.append("回收结果：\n");
                    ta.append(str);
                }
            }
            getavail();
            String str5 = "" + A;
            tf3.setText(str5);
            tf2.setText("");
        }
    }
}
